package SIC.Controleur;


import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

import org.semanticweb.owlapi.model.IRI;

import SIC.Controleur.Mapping.CorrespondancesCaoFao;
import SIC.Controleur.Mapping.Mapping;
import SIC.Controleur.OWL.GenerationOWL;
import SIC.Controleur.Reasoner.Reasoner;
import SIC.Modele.Data;
import SIC.Modele.DataBDD.DataBDD;
import SIC.Modele.DataExpress.DataExpress;

/**
 * C'est la classe principale qui permet de lancer toutes les opérations du programmes
 */
public class Controleur {

	//--------------------------------------------
	//					ATTRIBUTS
	//--------------------------------------------
	
	/** Dossier où l'on stocke les fichier OWL */
	private String dossierOWL = "DossierOWL/";
	
	/** Dossier où l'on stock les autres fichiers de données */
	private String dossierData = "DossierData/";
	
	/** Les données CAO */
	private Data cdCAO = new DataBDD("styloCAO");
	
	/** Les données FAO */
	private Data cdFAO = new DataExpress(dossierData + "styloFAO.exp");
	
	/** Le générateur de fichier OWL */
	private GenerationOWL owl = new GenerationOWL();
	
	/** Fichier de correspondance */
	private String fichierCorresp = dossierData + "correspondances.xml";
	
	/** Les correspondances de produits entre CAO et FAO */
	private CorrespondancesCaoFao correspondances = new CorrespondancesCaoFao(fichierCorresp);
	
	/** Map les fichiers OWL du CAO et du FAO, puis génère de fichier de mapping OWL */
	private Mapping mapping = new Mapping(correspondances);
	
	/** Le raissonneur pour déduire les classes inférées */
	private Reasoner reasoner = new Reasoner();
	
	//URI ET FICHIERS OWL------------
	
	/** iri de base à tous les stylos */
	private String iri = "http://www.stylos.com/";
	
	
	/** Nom du fichier OWL pour le CAO */
	private String nomFichierOWLCAO = "styloCAO.owl";
	/** Dossier + fichier OWL */
	private String fichierOWLCAO = dossierOWL + nomFichierOWLCAO;
	/** URI pour le CAO */
	private IRI iriCAO = IRI.create(iri + "CAO/" + nomFichierOWLCAO + "#");
	
	
	/** Nom du fichier OWL pour le FAO */
	private String nomFichierOWLFAO = "styloFAO.owl";
	/** Dossier + fichier OWL */
	private String fichierOWLFAO = dossierOWL + nomFichierOWLFAO;
	/** URI pour le FAO */
	private IRI iriFAO = IRI.create(iri + "FAO/" + nomFichierOWLFAO + "#");

	
	/** Nom du fichier OWL pour la correspondance CAO et FAO */
	private String nomFichierOWLCAOFAO = "styloCAO_FAO.owl";
	/** Dossier + fichier OWL */
	private String fichierOWLCAOFAO = dossierOWL + nomFichierOWLCAOFAO;
	/** URI pour la correspondance CAO et FAO */
	private IRI iriCAOFAO = IRI.create(iri + "CAO-FAO/" + nomFichierOWLCAOFAO + "#");
	

	//--------------------------------------------
	//				CONSTRUCTEUR
	//--------------------------------------------
	
	/**
	 * On supprime les fichiers au lancement de l'application
	 */
	public Controleur()
	{
		deleteFiles();
	}
	
	
	//--------------------------------------------
	//	    LISTE DES OPERATIONS DISPONIBLES
	//--------------------------------------------
	
	/**
	 * Crée la base de données.
	 * Ajoute les produits et les compositions
	 */
	public void creerBDD()
	{
		((DataBDD) cdCAO).creerEtPeuplerTables();
	}
	
	/**
	 * Crée le fichier de correspondance au format xml
	 */
	public void creerFichierCorrespondance()
	{
		correspondances.creerFichierCorrespondance();
	}
	
	
	/**
	 * Charges les données CAO
	 */
	public String chargerDataCAO()
	{
		cdCAO.initData();
		return cdCAO.toStringProduits() + "\n" + cdCAO.toStringCompositions();
	}
	
	/**
	 * Charges les données FAO
	 */
	public String chargerDataFAO()
	{
		cdFAO.initData();
		return cdFAO.toStringProduits() + "\n" + cdFAO.toStringCompositions();
	}
	
	/**
	 * Crée le fichier OWL pour le CAO
	 */
	public String creerOWLCAO()
	{
		if(!(new File(fichierOWLCAO).exists()))
		{
			owl.setData(cdCAO);
			owl.createOntologie(iriCAO, fichierOWLCAO);
		}
		return lireFichier(fichierOWLCAO);
	}
	
	/**
	 * Crée le fichier OWL pour le FAO
	 */
	public String creerOWLFAO()
	{
		if(!(new File(fichierOWLFAO).exists()))
		{
			owl.setData(cdFAO);
			owl.createOntologie(iriFAO, fichierOWLFAO);
		}
		return lireFichier(fichierOWLFAO);

	}
	
	/**
	 * Charge les données du fichier de correspondance CAO - FAO
	 */
	public String chargerCorrespondancesCAOFAO()
	{
		correspondances.load();
		return correspondances.toString();
		
	}
	
	/**
	 * Crée le fichier de mapping OWL
	 */
	public String creerFichierMappingOWL()
	{
		mapping.creerOWLMapping(iriCAOFAO, fichierOWLCAOFAO, iriCAO, fichierOWLCAO, iriFAO, fichierOWLFAO);
		return lireFichier(fichierOWLCAOFAO);
	}
	
	/**
	 * Fait tourner le raisonneur sur le fichier de mapping
	 */
	public String lancerReasoner()
	{
		reasoner.lancerRaisonneur(fichierOWLCAOFAO, fichierOWLCAO, fichierOWLFAO);
		
		String res = reasoner.toString();
		res = res.replace(iriCAO.toString(), "CAO:");
		res = res.replace(iriFAO.toString(), "FAO:");
		res = res.replaceAll("[<>{}]","");
		
		return res + "L'affichage de la hiérarchie à été simplifié (pas d'iri).";
	}	
	
	/**
	 * Supprime tous les fichiers OWL
	 */
	private void deleteFiles()
	{
		new File(fichierOWLCAO).delete();
		new File(fichierOWLFAO).delete();
		new File(fichierOWLCAOFAO).delete();
	}
	
	//--------------------------------------------
	//	    	 OPERATIONS INTERNES
	//--------------------------------------------
	
	/**
	 * Lis le fichier passé en paramètre
	 * @param fichier chemin jusqu'à un fichier
	 * @return retourne une chaine de caractère qui contient le contenu du fichier
	 */
	private String lireFichier(String fichier)
	{
		String resultat = "";
		
		File file = new File(fichier);
		
		if(file.exists())
		{
			try {
				Scanner scanner = new Scanner(file);
				while (scanner.hasNextLine()) resultat += scanner.nextLine() + "\n";
				scanner.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}
		
		
		return resultat;	
	}
}
